<?php
class Pageley_Domain_BasicType {
    private $namespace;
    private $name;
    private $attributes;
    private $parentType;
    private $mergedAttributes;
    private $className;

    public function __construct($namespace, $name, $attributes = null, $parentType = null, $className = null) {
        $this->namespace = $namespace;
        $this->name = $name;
        $this->attributes = $attributes;
        $this->parentType = $parentType;
        $this->className = $className;
    }

    public function getName() {
        return $this->name;
    }

    public function getFullName() {
        return $this->namespace . "." . $this->name;
    }

    public function getNamespace() {
        return $this->namespace;
    }

    public function getParentType() {
        return $this->parentType;
    }

    public function getAttributes() {
        $attributes = $this->mergedAttributes;
        if($attributes === null) {
            $attributes = new Pageley_Util_ArrayMap();
            $attributes->putAll($this->attributes);
            if($this->parentType != null) {
                $attributes->putAll($this->parentType->getAttributes());
            }
            $this->mergedAttributes = $attributes;
        }
        return $attributes;
    }

    public function setAttributes($attributes) {
        $this->attributes = $attributes;
    }

    public function getAttribute($propertyName) {
        $subpropertyName = null;
        if(Pageley_Util_String::contains($propertyName, ".")) {
            $subpropertyName = Pageley_Util_String::substringAfter($propertyName, ".");
            $propertyName = Pageley_Util_String::substringBefore($propertyName, ".");
        }
        $attribute = $this->attributes->get($propertyName);
        if($subpropertyName !== null) {
            $attribute = $attribute->getAttribute($subpropertyName);
        }
        if($attribute === null && $this->parentType != null) {
            $attribute = $this->parentType->getAttribute($propertyName);
        }
        if($attribute === null) {
            throw new Pageley_Domain_IllegalAttributeException("No such property: '" . $this->getName() . "." . $propertyName . "'.");
        }
        return $attribute;
    }

    public function newInstance() {
        $entity = null;
        if($this->className != null) {
            $entity = Pageley_Util_Reflection::newInstance($this->className);
        } else {
            $entity = new Pageley_Domain_BasicEntity($this);
        }
        return $entity;
    }

    public function __toString() {
        return $this->getFullName();
    }

    public function isAssignableTo($type) {
        $result = false;
        if($type !== null) {
            if($this->equals($type)) {
                $result = true;
            } else if($this->parentType != null) {
                $result = $this->parentType->isAssignableTo($type);
            }
        }
        return $result;
    }

    public function setClassName($className) {
        $this->className = $className;
    }

    public function equals($type) {
        if($type === null) {
            return false;
        }
        if(!($type instanceof Pageley_Domain_BasicType)) {
            return false;
        }
        return $this->name == $type->getName() &&
            (($this->namespace === null && $type->getNamespace() === null) ||
                $this->namespace->equals($type->getNamespace()));
    }
}